<?php
	require_once(dirname(__FILE__)."/incluir.php");
	require_once(dirname(__FILE__)."/dados.php");
	require_once(dirname(__FILE__)."/RegrasValidacao.php");
	class Validacao
	{
		// Dados do campo que irá validar
		public $nome_campo;
		public $sufixo;
		
		// Dados da validação
		public $mensagem_erro;
		public $funcao_validacao;
		private $campo_compara;
		private $erro; // valerá true se a validação obteve erro
		
		public function __construct($nome_campo, $sufixo, $funcao_validacao = 'notEmpty', $mensagem_erro = null, $campo_compara = null)
		{
			$mensagem_erro = ($mensagem_erro == null) ? "O campo $nome_campo não pode estar vazio" : $mensagem_erro;

			$this->nome_campo = $nome_campo;
			$this->sufixo = $sufixo;
			$this->funcao_validacao = $funcao_validacao;
			$this->mensagem_erro = $mensagem_erro;
			$this->campo_compara = $campo_compara;
		}
		
		private function get_valor_campo($dados, $nome = null, $sufixo = null)
		{
			$valor_campo = null;
			$nome = ($nome == null) ? $this->nome_campo : $nome;
			$sufixo = ($sufixo == null) ? $this->sufixo : $sufixo;
			
			if(isset($dados[$nome])) {
				$valor_campo = $dados[$nome];
			}
			// Se não tem em $dados o valor do campo, tenta o valor do nome do campo com o sufixo passado
			else if(isset($dados[$nome.$sufixo])){
				$valor_campo = $dados[$nome.$sufixo];
			}
			
			return $valor_campo;
		}
		
		// Retorna false se não validou
		public function valida($dados)
		{
			$valor_campo = $this->get_valor_campo($dados);
			$this->erro = false;
			
			// Caso especial para se a função deve comparar valores
			if($this->funcao_validacao == 'equals')
			{
				$valor_compara = $this->get_valor_campo($dados, $this->campo_compara);
				if(isset($valor_compara))
				{
					if( !(call_user_func('equals', $valor_campo, $valor_compara)) )
					{
						$this->erro = true; 
					}
				}
			}						
			else if( !(call_user_func($this->funcao_validacao, $valor_campo)) ) // Se não validou
			{
				$this->erro = true; 
			}
			
			// Se teve erro, então não validou. Logo o valor de retorno é o contrario do valor de $this->erro
			return !($this->erro); 
		}
		
		public function teve_erro()
		{
			return $this->erro;
		}
		
		// MENSAGENS DE ERRO DOS CAMPOS DOS VIALES PODEM SER MUDADAS NESSA PARTE
		
		// Recebe o nome de um campo e o seu tipo no banco de dados e acha qual seria o seu array de validação
		public static function acha_validacao($nome, $sufixo, $tipo, $tabela = null, $campo_compara = null)
		{
			$validacoes = array();
			
			// Tipos de validação: notEmpty, numerico, email, telefone, cpf, data, maxLength, equals
			
			// Se tabela foi passada tenta incluir o arquivo de dados da entidade a ser validada
			if(isset($tabela))
			{
				require(dirname(__FILE__)."/../$tabela/dados.php");
			}
			
			// Checagem pelo nome
			
			// Cria a mensagem de erro padrão para campos que não podem ser vazios
			$mensagem_erro_not_empty = isset($mensagens_erro[$nome."_not_empty"]) ? $mensagens_erro[$nome."_not_empty"] : "O campo $nome não pode estar vazio";
			
			if(stristr($nome, 'email') != false)
			{
				array_push($validacoes, new Validacao($nome, $sufixo, 'notEmpty', $mensagem_erro_not_empty));
				$mensagem_erro_email = isset($mensagens_erro[$nome]) ? $mensagens_erro[$nome] : 'O campo deve conter um email válido'; 
				array_push($validacoes, new Validacao($nome, $sufixo, 'email', $mensagem_erro_email));
			}
			else if(stristr($nome, 'telefone') != false)
			{
				array_push($validacoes, new Validacao($nome, $sufixo, 'notEmpty',$mensagem_erro_not_empty));
				$mensagem_erro = isset($mensagens_erro[$nome]) ? $mensagens_erro[$nome] : 'O campo deve conter um telefone válido';
				array_push($validacoes, new Validacao($nome, $sufixo, 'telefone', $mensagem_erro));
			}
			else if(stristr($nome, 'cpf') != false)
			{
				array_push($validacoes, new Validacao($nome, $sufixo, 'notEmpty',$mensagem_erro_not_empty));
				$mensagem_erro = isset($mensagens_erro[$nome]) ? $mensagens_erro[$nome] : 'O campo deve conter um cpf válido';
				array_push($validacoes, new Validacao($nome, $sufixo, 'cpf', $mensagem_erro));
			}
			
			// Checagem pelo tipo
			
			else if( (stristr($tipo, 'varchar') != false) || (stristr($tipo, 'text') != false) )
			{
				array_push($validacoes, new Validacao($nome, $sufixo, 'notEmpty', $mensagem_erro_not_empty));
			}
			else if(stristr($tipo, 'date') != false)
			{
				array_push($validacoes, new Validacao($nome, $sufixo, 'notEmpty', $mensagem_erro_not_empty));
				$mensagem_erro = isset($mensagens_erro[$nome]) ? $mensagens_erro[$nome] : 'O campo deve conter uma data válida';
				array_push($validacoes, new Validacao($nome, $sufixo, 'data', $mensagem_erro));
			}
			else if((stristr($tipo, 'int') != false) || (stristr($tipo, 'double') != false) ||
					(stristr($tipo, 'float') != false) || (stristr($tipo, 'decimal') != false))
			{
				// Se for vazio essa checagem falha
				$mensagem_erro = isset($mensagens_erro[$nome]) ? $mensagens_erro[$nome] : 'O campo deve conter um número';
				array_push($validacoes, new Validacao($nome, $sufixo, 'numerico', $mensagem_erro));
			}
			else
			{
				array_push($validacoes, new Validacao($nome, $sufixo, 'notEmpty', $mensagem_erro_not_empty));
			}
			// Se for um campo de confirmação de dados
			if(stristr($nome, 'confirma') != false)
			{
				$mensagem_erro = isset($mensagens_erro[$nome."_confirma"]) ? $mensagens_erro[$nome."_confirma"] : "Os valores de $nome e de $campo_compara devem ser iguais";
				array_push($validacoes, new Validacao($nome, $sufixo, 'equals', $mensagem_erro, $campo_compara));
			}
			return $validacoes;
		}
		
		// Recebe o nome de um campo e o seu tipo (data, file, password, telefone, text, textarea, select, numero) e acha qual seria o seu array de validação
		public static function acha_validacao_array($nome, $tipo, $mensagens_erro = null, $campo_compara = null)
		{
			$tipo_banco = $tipo; // Guardará qual será o equivalente ao tipo passado se o campo estivesse no banco de dados
			switch($tipo)
			{
				case 'data':
					$tipo_banco = 'date';
					break;
				case 'text': case 'texto': case 'password':
					$tipo_banco = 'varchar';
					break;
				case 'textarea':
					$tipo_banco = 'text';
					break;
				case 'numero':
					$tipo_banco = 'int';
					break;
			}
			$validacoes = Validacao::acha_validacao($nome, null, $tipo_banco, $campo_compara);
			if(isset($mensagens_erro))
			{
				if(is_array($mensagens_erro)) // Associa cada validacao a uma mensagem de erro
				{
					foreach($mensagens_erro as $index => $mensagem_erro)
					{
						$validacoes[$index]->mensagem_erro = $mensagem_erro; // modifico as mensagens de erro
					}
				}
				else // Se entrar nesse else, então só existe uma validação
				{
					$validacoes[0]->mensagem_erro = $mensagens_erro;
				}
			}
			return $validacoes;	
		}
	}
?>